package com.java1234.common.security;

import com.java1234.common.exception.UserCountLockException;
import com.java1234.entity.SysUser;
import com.java1234.service.SysUserService;
import com.java1234.util.DecryptUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MyUserDetailsServiceImpl implements UserDetailsService, AuthenticationProvider {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private DecryptUtil decryptUtil;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser sysUser = sysUserService.getByUsername(username);
        if (sysUser == null) {
            throw new UsernameNotFoundException("用户名或者密码错误！");
        } else if ("1".equals(sysUser.getStatus())) {
            throw new UserCountLockException("该用户账号被封禁，具体请联系管理员！");
        }
        return new User(sysUser.getUsername(), sysUser.getPassword(), getUserAuthority(sysUser.getId()));
    }

    List<GrantedAuthority> getUserAuthority(Long userId) {
        String authority = sysUserService.getUserAuthorityInfo(userId);
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authority);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String encryptedPassword = (String) authentication.getCredentials();

        // 加载用户信息
        UserDetails userDetails = loadUserByUsername(username);

        try {
            // 尝试解密客户端发送的密码
            String decryptedPassword = decryptUtil.decrypt(encryptedPassword);

            // 验证解密后的密码与存储的哈希密码是否匹配
            if (bCryptPasswordEncoder.matches(decryptedPassword, userDetails.getPassword())) {
                return new UsernamePasswordAuthenticationToken(userDetails, decryptedPassword, userDetails.getAuthorities());
            } else {
                throw new BadCredentialsException("Invalid password");
            }
        } catch (Exception e) {
            // 捕获解密失败或其他异常情况
            System.out.println("Failed to decrypt the password or verify it: " + e.getMessage());
            throw new BadCredentialsException("Failed to decrypt or verify the password", e);
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}